# chatbot.py

from abc import ABC, abstractmethod

from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder  # 导入提示模板相关类
from langchain_core.runnables.history import RunnableWithMessageHistory  # 导入带有消息历史的可运行类

from logger import LOG  # 导入日志工具
from chat_history import get_session_history


class ChatBot(ABC):
    """
    聊天机器人基类，提供聊天功能。
    """
    def __init__(self, prompt_file="./prompts/chatbot.txt", session_id=None, api_key=None, model="Doubao-1.5-pro-32k", api_url="https://ark.cn-beijing.volces.com/api/v3"):
        self.prompt_file = prompt_file
        self.session_id = session_id if session_id else "default_session_id"
        self.prompt = self.load_prompt()
        # LOG.debug(f"[ChatBot Prompt]{self.prompt}")
        self.api_key = api_key
        self.model = model
        self.api_url = api_url
        self.create_chatbot()


    def call_doubao_api(self, messages):
        """
        调用豆包大模型 API。

        参数:
            messages (list): 包含聊天历史的消息列表

        返回:
            object: API 响应对象
        """
        headers = {
            "Authorization": f"Bearer {self.api_key}",
            "Content-Type": "application/json"
        }

        data = {
            "model": self.model,
            "messages": messages,
            "max_tokens": 1024,
            "temperature": 0.8,
            "top_p": 0.95
        }

        try:
            response = requests.post(self.api_url, headers=headers, data=json.dumps(data))
            response.raise_for_status()
            return response
        except requests.exceptions.RequestException as e:
            LOG.error(f"API 请求错误: {e}")
            raise
        except json.JSONDecodeError as e:
            LOG.error(f"JSON 解码错误: {e}")
            raise
        except Exception as e:
            LOG.error(f"发生错误: {e}")
            raise

    def load_prompt(self):
        """
        从文件加载系统提示语。
        """
        try:
            with open(self.prompt_file, "r", encoding="utf-8") as file:
                return file.read().strip()
        except FileNotFoundError:
            raise FileNotFoundError(f"找不到提示文件 {self.prompt_file}!")


    def create_chatbot(self):
        """
        初始化聊天机器人，包括系统提示和消息历史记录。
        """
        # 创建聊天提示模板，包括系统提示和消息占位符
        system_prompt = ChatPromptTemplate.from_messages([
            ("system", self.prompt),  # 系统提示部分
            MessagesPlaceholder(variable_name="messages"),  # 消息占位符
        ])

        # 初始化聊天机器人，传入豆包大模型 API 密钥
        self.chatbot = ChatBot(api_key="958")

        # 将聊天机器人与消息历史记录关联
        self.chatbot_with_history = RunnableWithMessageHistory(self.chatbot, get_session_history)


    def chat_with_history(self, user_input, session_id=None):
        """
        处理用户输入，生成包含聊天历史的回复。

        参数:
            user_input (str): 用户输入的消息
            session_id (str, optional): 会话的唯一标识符

        返回:
            str: AI 生成的回复
        """
        if session_id is None:
            session_id = self.session_id
    
        # response = self.chatbot_with_history.invoke(
        #     [HumanMessage(content=user_input)],  # 将用户输入封装为 HumanMessage
        #     {"configurable": {"session_id": session_id}},  # 传入配置，包括会话ID
        # )
        # 调用豆包大模型 API
        response = self.call_doubao_api(messages)

        LOG.debug(f"[ChatBot] {response.content}")  # 记录调试日志
        return response.content  # 返回生成的回复内容